package javax.per.toolkit.file;
import info.monitorenter.cpdetector.io.ASCIIDetector;
import info.monitorenter.cpdetector.io.CodepageDetectorProxy;
import info.monitorenter.cpdetector.io.JChardetFacade;
import info.monitorenter.cpdetector.io.ParsingDetector;
import info.monitorenter.cpdetector.io.UnicodeDetector;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.charset.Charset;


/**
 * Test for detecting a file's encoding type<br/>
 * Need antlr.jar cpdetector.jar jchardet.jar
 * 
 *<br/><br/>
 *<strong>Test code</strong><br/>
 *	public static void main(String[] args){<br/>
 *		new DetectFileEncoding().charsetName("Filepath");<br/>
 *	}<br/>
 *
 * @author yl34569
 *
 */
public class DetectEncoding {
	
	
	private static CodepageDetectorProxy detector=null;
	
	/**
	 * Invoke the init function to initialize
	 */
	public DetectEncoding(){
		init();
	}
	
	static{
			detector=CodepageDetectorProxy.getInstance();
			detector.add(new ParsingDetector(false));
			detector.add(JChardetFacade.getInstance());
			detector.add(ASCIIDetector.getInstance());  
	        detector.add(UnicodeDetector.getInstance());
	}
	
	/**
	 * Do something to initialize
	 */
	protected void init(){
		
	}
	
	/**
	 * Get a file's encoding type from a file
	 * @param file a instance of File class
	 * @return charset name
	 */
	@SuppressWarnings("deprecation")
	protected String charsetName(File file){
	    Charset charset=null;
	        try {
				charset=detector.detectCodepage(file.toURL());
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
	    return charset.name();
	}
	
	/**
	 * Get a file's encoding type from the path of the file
	 * @param filePath the path of the file
	 * @return charset name
	 */
	@SuppressWarnings("deprecation")
	protected String charsetName(String filePath){
		File file=new File(filePath);
        Charset charset=null;
            try {
            	charset=detector.detectCodepage(file.toURL());
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
        return charset.name();
	}
	
	/**
	 * Get a file's encoding type from a input stream
	 * @param is a input stream which support mark
	 * @param length length of bytes to be check
	 * @return charset name
	 */
	protected String charsetName(InputStream is,int length){
        Charset charset=null;
            try {
    			charset=detector.detectCodepage(is,length);
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
        return charset.name();
	}
	
	/**
	 * Get a file's encoding type from a byte array
	 * @param bs the array to be detected.
	 * @return charset name
	 */
	protected String charsetName(byte[] bs,int length){
        Charset charset=null;
            try {
            	ByteArrayInputStream bais=new ByteArrayInputStream(bs);
            		charset=detector.detectCodepage(bais,length);
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
        return charset.name();
	}
	
	
	/**
	 * Get a file's encoding type from a file
	 * @param file a instance of File class
	 * @return charset name
	 */
	public static String getEncoding(File file){
		return new DetectEncoding().charsetName(file);
	}
	
	/**
	 * Get a file's encoding type from the path of the file
	 * @param filePath the path of the file
	 * @return charset name
	 */
	public static String getEncoding(String filePath){
		return new DetectEncoding().charsetName(filePath);
	}
	
	/**
	 * Get a file's encoding type from a input stream
	 * @param is a input stream which support mark
	 * @param length length of bytes to be check
	 * @return charset name
	 */
	public static String getEncoding(InputStream is,int length){
		return new DetectEncoding().charsetName(is,length);
	}
	
	/**
	 * Get a file's encoding type from a byte array
	 * @param bs the array to be detected.
	 * @return charset name
	 */
	public static String getEncoding(byte[] bs){
		return new DetectEncoding().charsetName(bs,bs.length);
	}
	
	/**
	 * Get a file's encoding type from a byte array
	 * @param bs the array to be detected.
	 * @param length length to be detected.
	 * @return charset name
	 */
	public static String getEncoding(byte[] bs,int length){
		return new DetectEncoding().charsetName(bs,length);
	}

}
